<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">

<head>
	<meta http-equiv="content-type" content="text/html;charset=utf-8" />
	<title>AXL Tutorial: TranzAm</title>
	<link href="style.css" rel="stylesheet" type="text/css" />
</head>
<body>
<!-- menu -->
	<div id="navmain">
	<ul>
		<li><a href="index.html">Overview</a></li>
		<li><a href="install.html">Installation</a></li>
		<li><a href="config.html">Configurator</a></li>
		<li><a href="animation.html">Animation</a></li>
		<li><a href="framework.html">Framework</a></li>
		<li><a href="tranzam.html">Tutorial</a></li>
	</ul>
	</div>
	<div id="navsub">
	<ul>
		<li><a href="tranzam.html">Start</a></li>
		<li><a href="tranzam_a1.html">Article 1</a></li>
		<li><a href="tranzam_a2.html">Article 2</a></li>
		<li><a href="tranzam_a3.html">Article 3</a></li>
		<li><a href="tranzam_a4.html">Article 4</a></li>
		<li><a href="tranzam_a5.html">Article 5</a></li>
		<li><a href="tranzam_a6.html">Article 6</a></li>
		<li><a href="tranzam_a7.html">Article 7</a></li>
		<li><a href="tranzam_a8.html">Article 8</a></li>
		<li><a href="tranzam_a9.html">Article 9</a></li>
		<li><a href="tranzam_a10.html">Article 10</a></li>
	</ul><span class="smallprint">This menu will stay fixed with a proper browser.</span>
	<p>
	 <a href="http://jigsaw.w3.org/css-validator/">
	  <img style="border:0;width:88px;height:31px"
		   src="http://jigsaw.w3.org/css-validator/images/vcss" 
		   alt="Valid CSS!" />
	 </a>
	</p>
	<p>
      <a href="http://validator.w3.org/check?uri=referer"><img
          src="http://www.w3.org/Icons/valid-xhtml10"
          alt="Valid XHTML 1.0!" height="31" width="88" /></a>
    </p>
<p><a href="http://www.bloggerheads.com/bbc/"><img src="http://www.bloggerheads.com/bbc/bbc.gif" width="90" height="45"  
alt="Click here to find out why." /></a></p>
<p><a href="http://retrospec.sgn.net" ><img src="retrospec.gif" width="150" alt="Fine games" /></a></p>
	</div>
<!-- menu -->

	<div id="main">
	<a name="files"></a>
<h1>Introduction</h1>
This lesson will get us loading the map and scrolling around it using the cursors.

<h1>Structure</h1>
    Despite all good programming practices, most games will end up with loads of global variables. Inevitabily they will be referenced in a dozen or so 
    files, all using the 'extern' statement.<br />
	To avoid having extern statements everywhere in our code and to make it easy to find globals, we've added a file 'game_vars.cpp'. All the global variables 
	for the game will now be declared in this file (in the previous lesson they were in the game_transam.cpp file), 
    and in the game_transam.h we've put an 'extern' in for every global. Because we link to this header file, we have full access to the globals.<br />
	This is done so that adding a source file and having access to all our functions and globals within this source file is a simple matter of '#include "game_transam.h" 
	at the top of the file. <br />Edit the game_vars.cpp and the game_transam.h and you'll see references to the ones we created in the previous lesson, 
    e.g. GameFramework, DisplayPanel.
    <br />If you are manually creating the project 
    make file then use the one from lesson 1 and additionally you will need to add the files game_vars.cpp and mappyal.c (from the libraries directory).
	<a name="source1"></a>
<h1>Mappy</h1>
I guess now would be a time to talk about Mappy. Mappy is a tile mapping library and the playback library in contained within the file mappyal.c. Various versions exist,
we are using the Allegro version (hence the 'al' at the end). We will be discovering it's joys throughout the articles. It is contained in the file mappyal.c.
<br />However, our map is contained in the file 'tranzam.fmp'. If you wish to read up more on the file format then visit the website and download 
the full version which includes tutorials, etc. However, these lessons should be enough.<br />
Hopefully you will have downloaded the mappy editor as described in the first lesson. Run this and open up the tranzam.fmp file. This is our map. Have a play 
and rummage around, but remember to keep a backup in case you break anything.
<br />
<img src="images/tranzam_mappy.jpg" alt="mappy screenshot"/>
As you can see from the map (and the terrible graphics), it is composed of a grid of equally sized tiles. Our tiles are 32x32 pixels and in 16-bit colour. The default colour depth (and what is set currently in the XML configuration 
is 32 bit. So at some point we'll either increase the graphics, decrease the colour depth, or let allegro convert them automatically to 32-bit.<br />
The actual map is to the left (zoomed out), and the tiles to the right. There are a total of 100 tiles.
	<h1>game_transam.cpp source file</h1>
	There isn't much change here:
    <ol>
    <li>We will be displaying the map to the right of the display panel (lesson 1) so we calculate a few variables ScreenXOffset/ScreenYOffset and ShownMapWidth/ShownMapHeight. 
    These will give us the position and size of the map that we can display. The 'Configuration' class that comes with AXL (we defined it in lesson 1 as 'GameConfiguration') 
    has a number of values associated with it (they are structs), that describe various things:
        <ul><li>CapsGraphics: details on the screen, depth, window mode, etc.</li>
        <li>CapsSystem: details on how allegro is set to work</li>
        <li>CapsSound: details on how sound/music is to be used</li>
        <li>CapsActualSystem: what was set after allegro initialisation</li>
        </ul>
    So in the code we use this to get the screen size, <span class="code">GameConfiguration->CapsGraphics.ScrWidth</span> will get us the screen width.
    </li>
	<li>In the EndGame() function (what is called when we are about to exit the game) we've added the following call, <span class="code">MapFreeMem()</span>.
    This is a Mappy function and lets it clear all it's allocated memory and tidy up generally.</li>
    </ol>
    <h1>Configuration</h1>
	If you open up the config.xml file you will see lots of values, these are mostly self-describing but there is (should be) at the bottom, a full
	explanation. It is here that the width/height of the screen is set. 'Configuration' is the class that looks after the config.xml file and initialises allegro. 
    It reads the data from the XML, stores it in structs and 
	has methods for initialising, etc. Refer to the AXL documention for more details, but 'CapsGraphics' as mentioned above is one such 
    struct and contains the size of the screen. 'GameConfiguration' was described in lesson 1 and is our pointer to the Configuration class.
    <br />With lesson 1, have a play with some of the values of config.xml (make a backup first) and see what effect it has on the screen. A full log
    of what occurred during the reading of config.xml and the initialisation of Allegro can be found in the log files created after running the executable.
    <h1>game_game.cpp source file</h1>
    Most of the changes are in this file, and are:
    <ol>
    <li>Update our TransAmGameLogic(). Remember this is the function that is called once every frame so that we can update the game. In lesson 1, it 
    simply waited for the ESCape key to be pressed. In this lesson we will use it to handle the cursor keys and scroll the map.</li>
    <li>Update our TransAmGameDrawing(). In lesson 1, this simply cleared the drawing buffer and drew the panel. In this lesson 
    we will additionally draw the map.</li>
    <li>Add a function, NewLevel(), that will load up and initialise our map</li>
    </ol>
    <h1>Scrolling</h1>
    Imagine the picture below is a zoomed out image of our map, the red rectangle representing an area 800x600 pixels (i.e. enough to fill 
    a screen) and the whole picture is 8000x6000 pixels (obviously that's rather too large to handle comfortably, 
    but we are talking theoretically) and effectively represents an area of 10 screens by 10 screens.
    <img src="images/tranzam_scroll.jpg" alt="map" />
    If we represent the location of the top-left corner of the red rectangle by the variables VIEW_X and VIEW_Y and it's size being VIEW_W, VIEW_H we 
    can show how scrolling is performed.
    <br />
    Every time our drawing code is invoked we grab a portion of the main map image at location VIEW_X/VIEW_Y and of size VIEW_W/VIEW_H
    and send it to the drawing buffer/screen. If we increase VIEW_X/VIEW_Y by one every time we press cursor right, for example, we have 
    scrolling. If we increase VIEW_X/VIEW_Y by VIEW_W or VIEW_H every time then we are scrolling by one whole screen at a time (i.e. 
    we have screen flipping rather than scrolling). If the map is relatively small (e.g. a few screens wide/high) then almost all 
    computers will be able to cope with this sized image, if scrolling a bitmap is all that is required.
    <br />Now, we are using a tile map and we do not have a 8000x6000 pixel bitmap. But the same applies, the only difference is how 
    we obtain the bitmap representing the image at VIEW_X/VIEW_Y. If we were implementing our own tile map, we would have some kind of
    array of integers (e.g. TileMap[][]), each representing one tile. Each tile would be of the same size (e.g. 32x32 pixels). Because we know the size of
    each tile and the graphic for each tile we would locate the starting tile (top-left of our view window) in the array as something like 'VIEW_X/TILE_SIZE' and 'VIEW_Y/TILE_SIZE'. 
    We know how many tiles there are to draw (VIEW_W/TILE_SIZE and 
    VIEW_H/TILE_SIZE) and so a simple loop (e.g. 
    <div class="code">for(int y=VIEW_Y/TILE_SIZE; y&lt;VIEW_H/TILE_SIZE;y++)
        for(int x=VIEW_X/TILE_SIZE; x&lt;VIEW_W/TILE_SIZE;x++)
        {
            int Tile=TileMap[y][x];
            BITMAP* TileGfx=TileImages[Tile];
            draw_sprite(TileGfx,ScreenBuffer,x*TILE_SIZE,y*TILE_SIZE);
        }
    </div>Obviously this is not optimised and doesn't take into account partially visible tiles or include any error checking for invalid locations (i.e. the above loop/calculations will 
    draw and snap to whole tiles only). To get round this problem of scrolling by a number of pixels smaller than the tile 
    size, you could do various things, including increasing the size of the tile area retrieved (e.g. in the 'y' loop 
    above change it to 'int y=(VIEW_Y/TILE_SIZE)-1') and then offsetting this using the VIEW_X/VIEW_Y.
    <br />That's the theory (in simplistic terms). In this game, as mentioned earlier, we will be implementing a scrolling 
    tile map using the Mappy library.
    
    <h1>Drawing a Map</h1>
    Drawing and scrolling our map is rather simple with Mappy (and the principle applies to any scrolling). At the start of the game 
    we have (curtesy of Mappy) variables that tell us how big our map is, both in pixels and in tiles. 
    We have also calculated (as above) how big our map on the screen will be (effectively the whole screen starting from the edge of the display panel). 
    <br />What we now need are some variables to hold the position that we want to be at within the map (in pixels). We will start with the centre point of the map. 
    <br />To make the map scroll, whenever we move the cursors, we increase or decrease these variables. In our drawing code it is then simply a matter 
    of finding the start point of the tile map, offsetting it by our new amount and asking Mappy nicely to populate our drawing buffer with the map, starting from this point and being 
    the size of our display area.
    
    <h1>Code Walkthrough (game_game.cpp)</h1>
    First up we create our two variables to hold where on the map we want to display to the screen. These are mapXoff/mapYoff. Next, within TransAmGameLogic, 
    We load up the map (described later) if we are on a new level, and set the two mapXoff/mapYoff variables to be the mid-point of the map. Mappy defines four variables: 
    mapblockwidth/mapblockhieght and mapwidth/mapheight that show the size of each tile and the number of tiles in map.
    <br />Next we will check for cursor movement and update our two variables mapXoff/mapYoff accordingly.
    <br />Next we will call MapUpdateAnims(). This is a Mappy function to update any animations it has. Mappy lets you define animated tiles, and in our map
    we have defined a couple of tiles as being animated (twinkling water, reflecting gently from the sun's rays).
    <br />When you set up a map within Mappy, each tile can be given a level: BG, FG1, FG2, FG3. When using Mappy to draw the tilemap you tell it which of these levels you 
    wish to draw. This allows you to layer stuff, for example BG first, then your player (not defined within Mappy, but a standard sprite), then your FG1 tiles on top.
    <br />These layers are also useful for when your map has lots of different BG tiles (e.g. in TranzAm we have grass, sand, water) and you want to 
    place a similar graphic on top of these ground tiles.
    <br />Drawing the BG tiles is done via the MapDrawBGT() function, and drawing the FGx tiles is done via the MapDrawFG() function.
    <br />Using all that was said above, we call the two Mappy drawing functions using the variables we have calculated.
    <br /><strong>Note: in the mappy.txt file in the 'code/libraries' directory is a summary of the variables and functions that can be called.
    </strong>
    <br />Loading and setting up Mappy is simple enough and defined in the function NewLevel(). To load a map you use <span class="code">MapLoad ("transam.fmp")</span> or <span class="code">MapLoadVRAM ("transam.fmp")</span>.
    The difference is that the first loads using standard Allegro bitmaps, and the second uses Video memory. Our code checks what mode has been set (using the 
    Configurator class) and calls the relevant one.
    <br />Mappy is then initialised and we call two additional Mappy functions:
    <ul><li>MapGenerateYLookup(): Calling this may speed up searching for tiles</li>
    <li>MapInitAnims(): This initialises an Mappy animations</li>
    </ul>Compile and run. You should see something like below.
    <img src="images/tranzam_l1.jpg" alt="screenshot" />
    At this point, don't worry about any jerky scrolling, it will be fixed.
    
<h1>Next</h1>
In the next lesson, we'll be placing the car on the map/screen and the car will be doing the scrolling of the map.
</div>
</body>
</html>
